﻿///////////////////////////////////////////////////////////////////////////////
//
// This file is part of the BassDrop project
//   https://code.google.com/p/bass-drop/
//
//
// Creator:	Gergely Krajcsovszki (krajcsovszkig@hotmail.com)
// Date:	2014-03-01 13:30
//
//
// Copyright © 2013-2014. Gergely Krajcsovszki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BassDrop.Core.Common.Exceptions.Cloud;

namespace BassDrop.Core.Common.Cloud.Requests
{
	/// <summary>
	/// A cloud request that puts a file into the cloud
	/// Do not use this directly, instead request one from the RequestFactory!
	/// </summary>
	public class CloudRequestPut : CloudRequestBase
	{
		private string m_remotePath;
		private Uri m_localPath;

		/// <summary>
		/// Constructs a new put request
		/// </summary>
		/// <param name="remotePath">path to the file in the cloud</param>
		/// <param name="localPath">path to the file in the local filesystem</param>
		/// <param name="mergeable">Is this request allowed to be merged with others</param>
		public CloudRequestPut( string remotePath, Uri localPath, bool mergeable = true )
			: base( mergeable )
		{
			m_remotePath = remotePath;
			m_localPath = localPath;
		}

		/// <summary>
		/// Returns if the passed request can be merged into this one
		/// </summary>
		/// <param name="other"></param>
		/// <returns></returns>
		protected override bool CanMerge( CloudRequestBase other )
		{
			var putOther = other as CloudRequestPut;
			return putOther != null && putOther.m_remotePath == this.m_remotePath && putOther.m_localPath == this.m_localPath;
		}

		/// <summary>
		/// Merges the passed request into this one.
		/// May throw various exceptions if it cannot be merged, call CanMerge first to check if it can be done.
		/// </summary>
		/// <param name="other"></param>
		protected override void DoMerge( CloudRequestBase other )
		{
		}

		/// <summary>
		/// Determines if retrying the execution of this request may succeed given the passed
		/// exception has been thrown on the last try.
		/// </summary>
		/// <param name="e"></param>
		/// <returns></returns>
		protected override bool CanRepair( Exception e )
		{
			var cloudException = e as CloudExceptionBase;

			if ( cloudException != null && cloudException.Recoverable )
			{
				return true;
			}

			return false;
		}

		/// <summary>
		/// Executes this request on the passed connection
		/// </summary>
		/// <param name="connection"></param>
		protected override async Task DoExecute( CloudConnectionBase connection )
		{
			await connection.Put( m_remotePath, m_localPath );
		}
	}
}
